package com.pai4j.user.service.group;

import com.pai4j.common.util.JsonUtil;
import com.pai4j.common.util.RedisUtil;
import com.pai4j.domain.vo.response.group.GroupMemberResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 群成员缓存服务
 * 基于PAI4J项目的Redis缓存架构，提供群成员信息的高效缓存管理
 */
@Slf4j
@Service
public class GroupMemberCacheService {

    @Autowired
    private RedisUtil redisUtil;

    // 缓存键前缀
    private static final String GROUP_MEMBERS_KEY_PREFIX = "pai4j:group:members:";
    private static final String USER_GROUPS_KEY_PREFIX = "pai4j:user:groups:";
    private static final String GROUP_MEMBER_INFO_KEY_PREFIX = "pai4j:group:member:info:";
    private static final String GROUP_ADMINS_KEY_PREFIX = "pai4j:group:admins:";
    private static final String GROUP_OWNER_KEY_PREFIX = "pai4j:group:owner:";

    // 缓存过期时间
    private static final long CACHE_EXPIRE_HOURS = 24; // 24小时
    private static final long SHORT_CACHE_EXPIRE_MINUTES = 30; // 30分钟

    /**
     * 缓存群成员列表
     */
    public void cacheGroupMembers(String groupPaiId, List<GroupMemberResponseVO> members) {
        try {
            String key = GROUP_MEMBERS_KEY_PREFIX + groupPaiId;
            String membersJson = JsonUtil.toJsonString(members);
            // 使用RedisUtil设置缓存，过期时间转换为秒
            redisUtil.set(key, membersJson, CACHE_EXPIRE_HOURS * 3600);
            
            // 同时缓存成员账号集合，用于快速判断用户是否在群内
            Set<String> memberAccounts = members.stream()
                    .map(GroupMemberResponseVO::getUserAccount)
                    .collect(Collectors.toSet());
            String membersSetKey = key + ":set";
            // 先删除旧的集合，再添加新的
            redisUtil.sremove(membersSetKey);
            if (!memberAccounts.isEmpty()) {
                redisUtil.sadd(membersSetKey, memberAccounts);
                redisUtil.expire(membersSetKey, CACHE_EXPIRE_HOURS * 3600);
            }
            
            log.debug("缓存群 {} 成员列表，共 {} 个成员", groupPaiId, members.size());
        } catch (Exception e) {
            log.error("缓存群成员列表失败：groupPaiId={}", groupPaiId, e);
        }
    }

    /**
     * 获取缓存的群成员列表
     */
    @SuppressWarnings("unchecked")
    public List<GroupMemberResponseVO> getCachedGroupMembers(String groupPaiId) {
        try {
            String key = GROUP_MEMBERS_KEY_PREFIX + groupPaiId;
            String membersJson = redisUtil.get(key);
            if (StringUtils.isNotBlank(membersJson)) {
                return JsonUtil.fromJson(membersJson, List.class);
            }
        } catch (Exception e) {
            log.error("获取缓存群成员列表失败：groupPaiId={}", groupPaiId, e);
        }
        return null;
    }

    /**
     * 缓存用户加入的群聊列表
     */
    public void cacheUserGroups(String userAccount, List<GroupMemberResponseVO> groups) {
        try {
            String key = USER_GROUPS_KEY_PREFIX + userAccount;
            String groupsJson = JsonUtil.toJsonString(groups);
            redisUtil.set(key, groupsJson, CACHE_EXPIRE_HOURS * 3600);
            
            log.debug("缓存用户 {} 的群聊列表，共 {} 个群", userAccount, groups.size());
        } catch (Exception e) {
            log.error("缓存用户群聊列表失败：userAccount={}", userAccount, e);
        }
    }

    /**
     * 获取缓存的用户群聊列表
     */
    @SuppressWarnings("unchecked")
    public List<GroupMemberResponseVO> getCachedUserGroups(String userAccount) {
        try {
            String key = USER_GROUPS_KEY_PREFIX + userAccount;
            String groupsJson = redisUtil.get(key);
            if (StringUtils.isNotBlank(groupsJson)) {
                return JsonUtil.fromJson(groupsJson, List.class);
            }
        } catch (Exception e) {
            log.error("获取缓存用户群聊列表失败：userAccount={}", userAccount, e);
        }
        return null;
    }

    /**
     * 缓存群成员详细信息
     */
    public void cacheGroupMemberInfo(String groupPaiId, String userAccount, GroupMemberResponseVO memberInfo) {
        try {
            String key = GROUP_MEMBER_INFO_KEY_PREFIX + groupPaiId + ":" + userAccount;
            String memberJson = JsonUtil.toJsonString(memberInfo);
            redisUtil.set(key, memberJson, CACHE_EXPIRE_HOURS * 3600);
            
            log.debug("缓存群成员信息：group={}, user={}", groupPaiId, userAccount);
        } catch (Exception e) {
            log.error("缓存群成员信息失败：groupPaiId={}, userAccount={}", groupPaiId, userAccount, e);
        }
    }

    /**
     * 获取缓存的群成员详细信息
     */
    public GroupMemberResponseVO getCachedGroupMemberInfo(String groupPaiId, String userAccount) {
        try {
            String key = GROUP_MEMBER_INFO_KEY_PREFIX + groupPaiId + ":" + userAccount;
            String memberJson = redisUtil.get(key);
            if (StringUtils.isNotBlank(memberJson)) {
                return JsonUtil.fromJson(memberJson, GroupMemberResponseVO.class);
            }
        } catch (Exception e) {
            log.error("获取缓存群成员信息失败：groupPaiId={}, userAccount={}", groupPaiId, userAccount, e);
        }
        return null;
    }

    /**
     * 缓存群管理员列表
     */
    public void cacheGroupAdmins(String groupPaiId, Set<String> adminAccounts) {
        try {
            String key = GROUP_ADMINS_KEY_PREFIX + groupPaiId;
            // 先删除旧的集合
            redisUtil.sremove(key);
            if (!adminAccounts.isEmpty()) {
                redisUtil.sadd(key, adminAccounts);
                redisUtil.expire(key, CACHE_EXPIRE_HOURS * 3600);
            }
            
            log.debug("缓存群 {} 管理员列表，共 {} 个管理员", groupPaiId, adminAccounts.size());
        } catch (Exception e) {
            log.error("缓存群管理员列表失败：groupPaiId={}", groupPaiId, e);
        }
    }

    /**
     * 缓存群主信息
     */
    public void cacheGroupOwner(String groupPaiId, String ownerAccount) {
        try {
            String key = GROUP_OWNER_KEY_PREFIX + groupPaiId;
            redisUtil.set(key, ownerAccount, CACHE_EXPIRE_HOURS * 3600);
            
            log.debug("缓存群 {} 群主：{}", groupPaiId, ownerAccount);
        } catch (Exception e) {
            log.error("缓存群主信息失败：groupPaiId={}", groupPaiId, e);
        }
    }

    /**
     * 检查用户是否在群内（基于缓存）
     */
    public Boolean isUserInGroup(String groupPaiId, String userAccount) {
        try {
            String key = GROUP_MEMBERS_KEY_PREFIX + groupPaiId + ":set";
            return redisUtil.sIsMember(key, userAccount);
        } catch (Exception e) {
            log.error("检查用户是否在群内失败：groupPaiId={}, userAccount={}", groupPaiId, userAccount, e);
            return null;
        }
    }

    /**
     * 检查用户是否为群管理员（基于缓存）
     */
    public Boolean isUserGroupAdmin(String groupPaiId, String userAccount) {
        try {
            String key = GROUP_ADMINS_KEY_PREFIX + groupPaiId;
            return redisUtil.sIsMember(key, userAccount);
        } catch (Exception e) {
            log.error("检查用户是否为群管理员失败：groupPaiId={}, userAccount={}", groupPaiId, userAccount, e);
            return null;
        }
    }

    /**
     * 检查用户是否为群主（基于缓存）
     */
    public Boolean isUserGroupOwner(String groupPaiId, String userAccount) {
        try {
            String key = GROUP_OWNER_KEY_PREFIX + groupPaiId;
            String ownerAccount = redisUtil.get(key);
            return userAccount.equals(ownerAccount);
        } catch (Exception e) {
            log.error("检查用户是否为群主失败：groupPaiId={}, userAccount={}", groupPaiId, userAccount, e);
            return null;
        }
    }

    /**
     * 添加用户到群成员缓存
     */
    public void addUserToGroupCache(String groupPaiId, String userAccount) {
        try {
            String key = GROUP_MEMBERS_KEY_PREFIX + groupPaiId + ":set";
            redisUtil.sadd(key, userAccount);
            redisUtil.expire(key, CACHE_EXPIRE_HOURS * 3600);
            
            log.debug("添加用户到群成员缓存：group={}, user={}", groupPaiId, userAccount);
        } catch (Exception e) {
            log.error("添加用户到群成员缓存失败：groupPaiId={}, userAccount={}", groupPaiId, userAccount, e);
        }
    }

    /**
     * 从群成员缓存中移除用户
     */
    public void removeUserFromGroupCache(String groupPaiId, String userAccount) {
        try {
            String key = GROUP_MEMBERS_KEY_PREFIX + groupPaiId + ":set";
            redisUtil.sremove(key, userAccount);
            
            // 同时清除用户的群成员详细信息缓存
            String memberInfoKey = GROUP_MEMBER_INFO_KEY_PREFIX + groupPaiId + ":" + userAccount;
            redisUtil.remove(memberInfoKey);
            
            log.debug("从群成员缓存中移除用户：group={}, user={}", groupPaiId, userAccount);
        } catch (Exception e) {
            log.error("从群成员缓存中移除用户失败：groupPaiId={}, userAccount={}", groupPaiId, userAccount, e);
        }
    }

    /**
     * 清除群相关的所有缓存
     */
    public void clearGroupCache(String groupPaiId) {
        try {
            String pattern = "*" + groupPaiId + "*";
            Set<String> keys = redisUtil.keys(pattern);
            if (keys != null && !keys.isEmpty()) {
                redisUtil.removeAll(keys);
                log.debug("清除群 {} 相关缓存，共 {} 个键", groupPaiId, keys.size());
            }
        } catch (Exception e) {
            log.error("清除群缓存失败：groupPaiId={}", groupPaiId, e);
        }
    }

    /**
     * 清除用户相关的群聊缓存
     */
    public void clearUserGroupCache(String userAccount) {
        try {
            String key = USER_GROUPS_KEY_PREFIX + userAccount;
            redisUtil.remove(key);
            
            log.debug("清除用户 {} 的群聊缓存", userAccount);
        } catch (Exception e) {
            log.error("清除用户群聊缓存失败：userAccount={}", userAccount, e);
        }
    }

    /**
     * 刷新群成员缓存（用于成员变更后的缓存更新）
     */
    public void refreshGroupMemberCache(String groupPaiId) {
        try {
            // 清除现有缓存
            clearGroupCache(groupPaiId);
            log.debug("刷新群 {} 成员缓存", groupPaiId);
        } catch (Exception e) {
            log.error("刷新群成员缓存失败：groupPaiId={}", groupPaiId, e);
        }
    }
}
